﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using ServiceRanking;

namespace IRProject.Model
{
    class Model : IFtidfAlgorithmProvider
    {
        public List<PageData> pageList = new List<PageData>();

        public EventHandler<ProgressEventArgs> OnProgressChangeEvent;
        public delegate void OnUpdateResultHandler(object result);
        public OnUpdateResultHandler OnUpdateResultEvent;
        public List<ResultData> ResultDataList = new List<ResultData>();

        public Model()
        {

        }

        public TFIDFMeasure InitializeFtidfAlgorithm()
        {
            StopWordsHandler stopWords = new StopWordsHandler();
            TFIDFMeasure tfidf = new TFIDFMeasure();
            tfidf.OnProgressChangeEvent += OnProgressing;
            tfidf.OnProgressEndEvent += OnProgressEnd;
            tfidf.OnProgressStartEvent += OnProgressStart;
            return tfidf;
        }

        public void Load(string filePath)
        {
            int totalLines = CalculateDocLines(filePath);
            OnProgressStart("loading Docs...");
            using (StreamReader sr = new StreamReader(filePath, Encoding.UTF8))
            {
                List<string> termList = new List<string>();
                string line;
                bool htmlStartFlag = false;
                string htmlContent = "";
                PageData tempPage = new PageData();
                int i = 0;
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains("WARC-TREC-ID:")) tempPage.Id = line.Split(' ')[1];
                    if (line.Contains("<html xmlns") || htmlStartFlag) htmlStartFlag = true;
                    if (line.Contains("</html>")) htmlStartFlag = false;
                    if (htmlStartFlag)
                    {
                        htmlContent += line + " ";
                    }
                    if (!htmlStartFlag && htmlContent != "")
                    {
                        htmlContent = Regex.Replace(htmlContent, @"<script[\d\D]*?>[\d\D]*?</script>", String.Empty);
                        htmlContent = Regex.Replace(htmlContent, @"<[^>]*>", String.Empty);
                        tempPage.Content = htmlContent;
                        pageList.Add(tempPage);

                        tempPage = new PageData();
                        htmlContent = "";
                    }
                    i++;
                    OnProgressing(totalLines, i);
                }
            }
            OnProgressEnd();
        }

        public void InputQuery(String query)
        {
            //BoolenQueryHandler bq = new BoolenQueryHandler(this);
            //ResultDataList = bq.GetResultList(query); //結果
            //MessageBox.Show(ResultDataList.Count.ToString());
            QueryToTreeHandler QT = new QueryToTreeHandler(this);
            ResultDataList = QT.GetResultList(query);
            ResultDataList.Sort(new ResultOrderComparer());
        }

        public string[] Documents { get; private set; }

        public void AnalysisDocs()
        {
            OnProgressStart("AnalysisDocs...");
            //_tfidf=InitializeFtidfAlgorithm();
            Documents = new string[pageList.Count];
            for (int i = 0; i < pageList.Count; i++)
            {
                Documents[i] = pageList[i].Content;
                OnProgressing(pageList.Count, i);
            }
            OnProgressEnd();
            //_tfidf.LoadDocs(docs);
        }

        private int CalculateDocLines(string filePath)
        {
            using (StreamReader sr = new StreamReader(filePath, Encoding.UTF8))
            {
                string line;
                int ls = 0;
                while ((line = sr.ReadLine()) != null)
                {
                    ls++;
                }
                return ls;
            }
        }

        private int CalculateProgress(float total, float count)
        {
            int i = (int)(count * 100f / total);
            return i;
        }

        void OnProgressChange(ProgressEventArgs e)
        {
            if (OnProgressChangeEvent != null)
                OnProgressChangeEvent(this, e);
        }

        void OnProgressStart(string mes)
        {
            OnProgressChange(new ProgressEventArgs(mes, EProgressState.Start));
        }

        void OnProgressEnd()
        {
            OnProgressChange(new ProgressEventArgs(EProgressState.End));
        }

        void OnProgressing(float total, float count)
        {
            int p = CalculateProgress(total, count);
            OnProgressChange(new ProgressEventArgs(p));
        }

    }
}
